package com.jhx.video.cutvideo

import android.annotation.SuppressLint
import android.app.KeyguardManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Point
import android.os.AsyncTask
import android.os.Bundle
import android.os.Environment
import android.telephony.PhoneStateListener
import android.telephony.TelephonyManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.jhx.common.framework.QuickBaseFragment
import com.jhx.common.model.Event
import com.jhx.common.model.PlayState
import com.jhx.common.model.Video
import com.jhx.common.utils.centerToast
import com.jhx.video.R
import com.jhx.video.publish.VideoPublishFragment
import com.jhx.video.shortvideo.editor.VideoEditerActivity
import com.jhx.video.shortvideo.editor.VideoEditerWrapper
import com.jhx.video.shortvideo.editor.VideoPreprocessActivity
import com.jhx.video.shortvideo.editor.common.widget.videotimeline.RangeSliderViewContainer
import com.jhx.video.shortvideo.editor.common.widget.videotimeline.VideoProgressController
import com.jhx.video.shortvideo.editor.utils.TCEditerUtil
import com.jhx.video.utils.FileUtils
import com.jhx.video.utils.TCConstants
import com.jhx.video.utils.TCUtils
import com.jhx.video.widget.VideoWorkProgressFragment
import com.tencent.liteav.basic.log.TXCLog
import com.tencent.ugc.TXRecordCommon
import com.tencent.ugc.TXVideoEditConstants
import com.tencent.ugc.TXVideoEditer
import com.tencent.ugc.TXVideoInfoReader
import kotlinx.android.synthetic.main.fragment_cut_video.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
import java.lang.ref.WeakReference

/**
 *
 *
 * @author Jack 2018-03-17 16:10
 */
class CutVideoFragment : QuickBaseFragment(), VideoEditerWrapper.TXVideoPreviewListenerWrapper ,
    RangeSliderViewContainer.OnDurationChangeListener, TXVideoEditer.TXVideoGenerateListener{
    private var mVideoProgressController: VideoProgressController? = null
    private var mCutterRangeSliderView: RangeSliderViewContainer? = null
    private var mWorkLoadingProgress: VideoWorkProgressFragment? = null
    private var mPhoneListener: PhoneStateListener? = null
    private var mKeyguardManager: KeyguardManager? = null
    private var mTXVideoEditer: TXVideoEditer? = null
    /**
     * 预处理后的视频路径，裁剪后需要删除
     */
    private var mRecordProcessedPath: String? = null
    private var mVideoOutputPath: String? = null
    private var mCoverPath: String? = null
    private var mCutterStartTime: Long? = 0
    private var mCutterEndTime: Long? = 0
    private var mVideoResolution: Int = 0
    private var mVideoDuration: Long = 0
    private var mPreviewAtTime: Long = 0
    private var mCurrentState: Int = 0
    private var mVideoFrom: Int = 0

    private val mVideoProgressSeekListener = object : VideoProgressController.VideoProgressSeekListener {
        override fun onVideoProgressSeek(currentTimeMs: Long) {
            TXCLog.i(TAG, "onVideoProgressSeek, currentTimeMs = " + currentTimeMs)
            previewAtTime(currentTimeMs)
        }

        override fun onVideoProgressSeekFinish(currentTimeMs: Long) {
            TXCLog.i(TAG, "onVideoProgressSeekFinish, currentTimeMs = " + currentTimeMs)
            previewAtTime(currentTimeMs)
        }
    }

    override fun bindView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        return inflater.inflate(R.layout.fragment_cut_video, container, false)
    }

    @SuppressLint("MissingSuperCall")
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        setTitle("裁剪视频")
        setMenuText("完成")
        if(!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
        val wrapper = VideoEditerWrapper.getInstance()
        wrapper.addTXVideoPreviewListenerWrapper(this)
        mTXVideoEditer = wrapper.editer
        if (mTXVideoEditer == null || wrapper.txVideoInfo == null) {
            activity.centerToast("状态异常，结束编辑")
            pop()
            return
        }
        mVideoDuration = mTXVideoEditer?.txVideoInfo?.duration ?:0
        mVideoResolution = arguments.getInt(TCConstants.VIDEO_RECORD_RESOLUTION, -1)
        mVideoFrom = arguments.getInt(TCConstants.VIDEO_RECORD_TYPE)
        mRecordProcessedPath = arguments.getString(TCConstants.VIDEO_EDITER_PATH)
        mCoverPath = arguments?.getString(TCConstants.VIDEO_RECORD_COVERPATH)
        mKeyguardManager = activity.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
        mCutterEndTime = mVideoDuration
        initListener()
        // 开始预览视频
        previewVideo()
    }

    private fun initVideoProgressLayout() {
        val point = Point()
        activity.windowManager.defaultDisplay.getSize(point)
        val screenWidth = point.x
        editer_video_progress_view.viewWidth = screenWidth
        // 获取预处理的缩略图集合
        val thumbnailList = VideoEditerWrapper.getInstance().allThumbnails
        editer_video_progress_view.setThumbnailData(thumbnailList)

        mVideoProgressController = VideoProgressController(mVideoDuration)
        mVideoProgressController?.setVideoProgressView(editer_video_progress_view)
        mVideoProgressController?.setVideoProgressSeekListener(mVideoProgressSeekListener)
        mVideoProgressController?.setVideoProgressDisplayWidth(screenWidth)

    }

    private fun previewVideo() {
        // 初始化预览视频布局
        initPlayerLayout()
        // 初始化进度布局
        initVideoProgressLayout()
        // 初始化裁剪滑块
        initRangeSlider()
        // 开始播放
        startPlay(0, mVideoDuration)
    }

    private fun initPlayerLayout() {
        val param = TXVideoEditConstants.TXPreviewParam()
        param.videoView = editer_fl_video
        param.renderMode = TXVideoEditConstants.PREVIEW_RENDER_MODE_FILL_EDGE
        mTXVideoEditer?.initWithPreview(param)
    }

    /**
     * 调用mTXVideoEditer.previewAtTime后，需要记录当前时间，下次播放时从当前时间开始
     * x
     *
     * @param timeMs
     */
    fun previewAtTime(timeMs: Long) {
        pausePlay()
        mTXVideoEditer?.previewAtTime(timeMs)
        mPreviewAtTime = timeMs
        mCurrentState = PlayState.STATE_PREVIEW_AT_TIME
    }

    private fun initRangeSlider() {
        mCutterRangeSliderView = RangeSliderViewContainer(activity)
        mCutterRangeSliderView?.init(mVideoProgressController, 0, mVideoDuration, 30000)
        mCutterRangeSliderView?.setDurationChangeListener(this)
        mVideoProgressController?.addRangeSliderView(mCutterRangeSliderView)
    }

    private fun initListener() {
        //设置电话监听
        if (mPhoneListener == null) {
            mPhoneListener = TXPhoneStateListener(this)
            val tm = activity.getSystemService(Service.TELEPHONY_SERVICE) as TelephonyManager
            tm.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE)
        }

        editer_ib_play.setOnClickListener {
            if (mCurrentState == PlayState.STATE_NONE || mCurrentState == PlayState.STATE_STOP) {
                startPlay(mCutterStartTime, mCutterEndTime)
            } else if (mCurrentState == PlayState.STATE_RESUME || mCurrentState == PlayState.STATE_PLAY) {
                pausePlay()
            } else if (mCurrentState == PlayState.STATE_PAUSE) {
                resumePlay()
            } else if (mCurrentState == PlayState.STATE_PREVIEW_AT_TIME) {
                startPlay(mPreviewAtTime, mCutterEndTime)
            }
        }
    }

    override fun onMenuClick(view: View?) {
        super.onMenuClick(view)
        startGenerateVideo()
    }

    /*********************************************监听电话状态 */
    internal class TXPhoneStateListener(editer: CutVideoFragment) : PhoneStateListener() {
        private var mEditer: WeakReference<CutVideoFragment> = WeakReference(editer)

        override fun onCallStateChanged(state: Int, incomingNumber: String) {
            super.onCallStateChanged(state, incomingNumber)

        }
    }

    private fun startPlay(startTime: Long?, endTime: Long?) {
        if(startTime != null && startTime >= 0 && endTime != null && endTime >= 0) {
            mTXVideoEditer?.startPlayFromTime(startTime, endTime)
            mCurrentState = PlayState.STATE_PLAY
            editer_ib_play.setImageResource(R.drawable.ic_pause)
        }
    }


    private fun resumePlay() {
        if (mCurrentState == PlayState.STATE_PAUSE) {
            mTXVideoEditer?.resumePlay()
            mCurrentState = PlayState.STATE_RESUME
            editer_ib_play.setImageResource(R.drawable.ic_pause)
        }
    }

    private fun pausePlay() {
        if (mCurrentState == PlayState.STATE_RESUME || mCurrentState == PlayState.STATE_PLAY) {
            mTXVideoEditer?.pausePlay()
            mCurrentState = PlayState.STATE_PAUSE
            editer_ib_play.setImageResource(R.drawable.ic_play)
        }
    }

    private fun stopPlay() {
        if (mCurrentState == PlayState.STATE_RESUME || mCurrentState == PlayState.STATE_PLAY ||
                mCurrentState == PlayState.STATE_STOP || mCurrentState == PlayState.STATE_PAUSE) {
            mTXVideoEditer?.stopPlay()
            mCurrentState = PlayState.STATE_STOP
            editer_ib_play.setImageResource(R.drawable.ic_play)
        }
    }

    private fun restartPlay() {
        stopPlay()
        startPlay(mCutterStartTime, mCutterEndTime)
    }

    /**
     * 滑块滑动后的开始和结束时间
     */
    override fun onDurationChange(startTime: Long, endTime: Long) {
        mCutterStartTime = startTime
        mCutterEndTime = endTime
        mTXVideoEditer?.setCutFromTime(startTime, endTime)
        cutter_tv_tip.text = String.format("左侧 : %s, 右侧 : %s ", TCUtils.duration(startTime), TCUtils.duration(endTime))
        VideoEditerWrapper.getInstance().setCutterStartTime(startTime, endTime)
    }

    /**
     * 预览进度回调
     */
    override fun onPreviewProgressWrapper(time: Int) {
        // 视频的进度回调是异步的，如果不是处于播放状态，那么无需修改进度
        if (mCurrentState == PlayState.STATE_RESUME || mCurrentState == PlayState.STATE_PLAY) {
            mVideoProgressController?.currentTimeMs = time.toLong()
        }
    }

    /**
     * 预览完成回调
     */
    override fun onPreviewFinishedWrapper() {
        TXCLog.d(TAG, "---------------onPreviewFinished-----------------")
        stopPlay()
        // 如果当前不是动态滤镜界面或者时间特效界面，那么会自动开始重复播放
        startPlay(mCutterStartTime, mCutterEndTime)
    }

    @SuppressLint("MissingSuperCall")
    override fun onResume() {
        super.onResume()
        if (mKeyguardManager?.inKeyguardRestrictedInputMode() == false) {
            restartPlay()
        }
    }

    @SuppressLint("MissingSuperCall")
    override fun onPause() {
        super.onPause()
        pausePlay()
        // 若当前处于生成状态，离开当前activity，直接停止生成
        if (mCurrentState == PlayState.STATE_GENERATE) {
            stopGenerate()
        }
    }

    @SuppressLint("MissingSuperCall")
    override fun onStop() {
        super.onStop()
        if (mWorkLoadingProgress != null) {
            mWorkLoadingProgress?.dismiss()
        }
    }

    /**
     * 视频生成
     */
    private fun startGenerateVideo() {
        // 停止播放
        stopPlay()
        if(mCutterStartTime == null || mCutterEndTime == null) {
            return
        } else if(mCutterEndTime!! - mCutterStartTime!! > 30000 ||
                mCutterEndTime!! - mCutterStartTime!! < 5000) {
            activity.centerToast("视频长度必须在5s-30s之间~")
            return
        } else if(mCutterStartTime == 0L && mCutterEndTime == mVideoDuration) {
            // 跳转到编辑页面
            val intent = Intent(activity, VideoEditerActivity::class.java)
            val video = Video()
            video.countTime = mCutterEndTime!! - mCutterEndTime!!
            video.video_url = mVideoOutputPath
            video.cover_url = mCoverPath
            intent.putExtra(VideoPublishFragment.VIDEO_DATA, video)
            startActivity(intent)
            return
        }
        VideoEditerWrapper.getInstance().setCutterStartTime(mCutterStartTime!!, mCutterEndTime!!)
        // 处于生成状态
        mCurrentState = PlayState.STATE_GENERATE
        // 生成视频输出路径
        mVideoOutputPath = TCEditerUtil.generateVideoPath()

        editer_ib_play.setImageResource(R.drawable.ic_play)

        if (mWorkLoadingProgress == null) {
            initWorkLoadingProgress()
        }
        if (mWorkLoadingProgress?.isAdded == false &&
            mWorkLoadingProgress?.isVisible == false &&
            mWorkLoadingProgress?.isRemoving == false) {
            mWorkLoadingProgress?.setProgress(0)
            mWorkLoadingProgress?.isCancelable = false
            mWorkLoadingProgress?.show(childFragmentManager, "progress_dialog")
        }
        mTXVideoEditer?.setCutFromTime(mCutterStartTime!!, mCutterEndTime!!)
        mTXVideoEditer?.setVideoGenerateListener(this)
        // 默认情况下都将输出720的视频
        when (mVideoResolution) {
            -1 -> mTXVideoEditer?.generateVideo(TXVideoEditConstants.VIDEO_COMPRESSED_720P, mVideoOutputPath)
            TXRecordCommon.VIDEO_RESOLUTION_360_640 -> mTXVideoEditer?.generateVideo(TXVideoEditConstants.VIDEO_COMPRESSED_360P, mVideoOutputPath)
            TXRecordCommon.VIDEO_RESOLUTION_540_960 -> mTXVideoEditer?.generateVideo(TXVideoEditConstants.VIDEO_COMPRESSED_540P, mVideoOutputPath)
            TXRecordCommon.VIDEO_RESOLUTION_720_1280 -> mTXVideoEditer?.generateVideo(TXVideoEditConstants.VIDEO_COMPRESSED_720P, mVideoOutputPath)
        }
    }

    /**
     * 进度条
     */
    private fun initWorkLoadingProgress() {
        if (mWorkLoadingProgress == null) {
            mWorkLoadingProgress = VideoWorkProgressFragment()
            mWorkLoadingProgress?.setOnClickStopListener({ stopGenerate() })
        }
        mWorkLoadingProgress?.setProgress(0)
    }

    /**
     * 停止生成视频
     */
    private fun stopGenerate() {
        if (mCurrentState == PlayState.STATE_GENERATE) {
            mWorkLoadingProgress?.dismiss()
            activity.centerToast("取消视频生成")
            mWorkLoadingProgress?.setProgress(0)
            mCurrentState = PlayState.STATE_NONE
            if (mTXVideoEditer != null) {
                mTXVideoEditer?.cancel()
            }
        }
    }

    override fun onGenerateComplete(result: TXVideoEditConstants.TXGenerateResult?) {
        if (result?.retCode == TXVideoEditConstants.GENERATE_RESULT_OK) {
            // 生成成功
            createThumbFile()
        } else {
            activity.centerToast("${result?.descMsg}")
        }
        mCurrentState = PlayState.STATE_NONE
    }

    override fun onGenerateProgress(progress: Float) {
        mWorkLoadingProgress?.setProgress((progress * 100).toInt())
    }

    /**
     * 创建缩略图，并跳转至视频预览的Activity
     */
    private fun createThumbFile() {
        @SuppressLint("StaticFieldLeak")
        val task = @SuppressLint("StaticFieldLeak")
        object : AsyncTask<Void, String, String>() {
            override fun doInBackground(vararg voids: Void): String? {
                val outputVideo = File(mVideoOutputPath)
                if (!outputVideo.exists()) {
                    return null
                }
                val bitmap = TXVideoInfoReader.getInstance().getSampleImage(0, mVideoOutputPath) ?: return null
                var mediaFileName = outputVideo.absolutePath
                if (mediaFileName.lastIndexOf(".") != -1) {
                    mediaFileName = mediaFileName.substring(0, mediaFileName.lastIndexOf("."))
                }
                val folder = Environment.getExternalStorageDirectory().toString() + File.separator + TCConstants.DEFAULT_MEDIA_PACK_FOLDER + File.separator + mediaFileName
                val appDir = File(folder)
                if (!appDir.exists()) {
                    appDir.mkdirs()
                }

                val fileName = "thumbnail" + ".jpg"
                val file = File(appDir, fileName)
                try {
                    val fos = FileOutputStream(file)
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos)
                    fos.flush()
                    fos.close()
                } catch (e: FileNotFoundException) {
                    e.printStackTrace()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                return file.absolutePath
            }

            override fun onPostExecute(s: String) {
                try {
                    if (mVideoFrom == TCConstants.VIDEO_RECORD_TYPE_UGC_RECORD) {
                        FileUtils.deleteFile(mRecordProcessedPath)
                    }
                    mWorkLoadingProgress?.dismiss()
                    // 跳转到编辑页面
                    val intent = Intent(activity, VideoPreprocessActivity::class.java)
                    intent.putExtra(TCConstants.VIDEO_RECORD_TYPE, TCConstants.VIDEO_RECORD_TYPE_UGC_RECORD)
                    intent.putExtra(TCConstants.VIDEO_EDITER_PATH, mVideoOutputPath)
                    intent.putExtra(TCConstants.VIDEO_RECORD_COVERPATH, mCoverPath)
                    intent.putExtra(TCConstants.VIDEO_RECORD_TYPE, TCConstants.VIDEO_RECORD_TYPE_CUT)
                    intent.putExtra(TCConstants.VIDEO_RECORD_RESOLUTION, mVideoResolution)
                    startActivity(intent)
                    pop()
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }

        }
        task.execute()
    }

    override fun showToolbar(): Boolean {
        return true
    }

    override fun onDestroyView() {
        if(EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        super.onDestroyView()
    }

    @Subscribe
    fun onEvent(event: Event?) {
        if(event != null) {
            if (event.code == Video.CODE_POST_SUCCESS || event.code == Video.CODE_UPDATE) {
                stopPlay()
                pop()
            }
        }
    }
}